package com.dd.keel.core.framework.protocol;


import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dd.keel.core.common.utils.ByteUtil;
import com.dd.keel.core.common.utils.Crc32;

/**
 * Encode the response
 * @author Kevin.XU
 *
 */
public class SoaProtocolEncoder implements ProtocolEncoder{
	
	final static private Logger LOGGER = LoggerFactory.getLogger(SoaProtocolEncoder.class);
	
	public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception 
	{
		LOGGER.trace( "SoaProtocolEncoder :: send message");
		SoaMsg msg = (SoaMsg) message;
		if(msg.getBody()!=null){
			msg.setLength(msg.getBody().length);
		}else{
			msg.setLength(0);
		}
		long total_len = msg.getLength() + SoaMsg.MESSAGE_HEADER_LENGTH;
		byte[] datagram = new byte[ (int)total_len ];
		int off_pos = 4;
		ByteUtil.long2fourbyte(msg.getIdentifier(), datagram, off_pos);
		off_pos+=4;
		ByteUtil.long2fourbyte(msg.getLength(), datagram, off_pos);
		off_pos+=4;
		ByteUtil.int2onebyte(msg.getType(), datagram, off_pos);
		off_pos+=1;
		datagram[off_pos] = '\0';
		off_pos+=1;
		datagram[off_pos] = '\0';
		off_pos+=1;
		datagram[off_pos] = '\0';
		off_pos+=1;
		if(msg.getLength()>0){
			System.arraycopy( msg.getBody(), 0, datagram, off_pos, (int)msg.getLength() );
		}
		long crc = Crc32.crc32(datagram, 4, (int)(total_len-4));
		if(crc==-1){
			throw new Exception("crc make failed");
		}
		msg.setCrc(crc);
		ByteUtil.long2fourbyte(crc, datagram, 0);
		if(LOGGER.isTraceEnabled()){
			LOGGER.trace("@ send datagram to {}, {}", session.getRemoteAddress(), ByteUtil.byte2hex(datagram));
		}
		IoBuffer b = IoBuffer.allocate(datagram.length,false);
		//b.setAutoExpand(true);
		b.put(datagram);
		b.flip();
		out.write(b);
	}
	
    public void dispose(IoSession session) throws Exception {
        // not dispose
    }
	
}
